#pragma once
#include "FibonacciHeapNode.h"

namespace FibonacciHeapDetail
{
	template <typename Key>
	Node<Key>::Node()
	{
		_ppSelf = std::make_shared<Node*>(this);
	}

	template <typename Key>
	Node<Key>::~Node()
	{
		*_ppSelf = nullptr;
	}

	template <typename Key>
	auto Node<Key>::find(const Key& k)->Node*
	{
		if (_k == k)
			return this;

		for (auto pNode : _childen)
		{
			auto pTmpNode = pNode->find(k);
			if (pTmpNode)
				return pTmpNode;
		}

		return NULL;
	}

	template <typename Key>
	template <typename Func>
	auto Node<Key>::show(std::ostream& os, Func func) const->std::ostream&
	{
		if (_mark)
			os << "[";

		os << _k;

		if (_mark)
			os << "]";

		if (_childen.empty())
			return os;
		
		os << "={";
		bool first = true;
		for (auto pNode : _childen)
		{
			if (first) first = false;
			else os << ",";

			pNode->show(os, func);
		}

		return os << "}";
	}

	template <typename Key>
	bool Node<Key>::verify(Node* pParent, size_t& num)
	{
		if (_ppParent)
		{
			if (*_ppParent != pParent)
				return false;
		}
		else
		{
			if (pParent)
				return false;
		}

		if (!_ppSelf)
			return false;

		if (*_ppSelf != this)
			return false;

		size_t tmpNum = 1;
		for (auto pNode : _childen)
		{
			if (!pNode->verify(this, tmpNum))
				return false;
		}

		num += tmpNum;
		return true;
	}
}